package com.bidevalution.service.impl;

import com.bidevalution.core.constant.ApiConstant;
import com.bidevalution.core.constant.CharConstant;
import com.bidevalution.core.enums.ApiEnum;
import com.bidevalution.core.util.WebServiceUtils;
import com.bidevalution.dao.ApiEnterCheckItemMapper;
import com.bidevalution.dao.ApiEnterCheckMapper;
import com.bidevalution.dao.ApiSectionEnterpriseMapper;
import com.bidevalution.dao.ApiSectionInfoMapper;
import com.bidevalution.model.BlData;
import com.bidevalution.model.EnterCheck;
import com.bidevalution.model.EnterCheckItem;
import com.bidevalution.model.SectionInfo;
import com.bidevalution.service.EntInfoService;
import com.qtp.core.model.Response;
import com.qtp.core.util.DateUtil;
import com.qtp.core.util.GsonUtil;
import com.qtp.core.util.Md5Util;
import com.qtp.core.util.OConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author huyiqi
 * @date 2019/11/13
 */
@Service(value = "entInfoService")
public class EntInfoServiceImpl extends BaseServiceImpl implements EntInfoService {

    private static final Logger log = LoggerFactory.getLogger(EntInfoServiceImpl.class);

    private Pattern enterCheckPatten = Pattern.compile("Jzyw_EnterpriseSign\\$(.*)\\$Jzyw_EntPerCheckResult\\$(.*)");

    private static final String KEY_EXPERT_ERROR = "error";
    private static final String KEY_EXPERT_PERSON = "person";

    private static final String EXPERT_RESULT_INCOMPLETE = "专家验证接口返回值不完整";

    /**
     * 验证专家
     * @param cardId 身份证
     * @param name 专家姓名
     * @param segmentShowID 项目编码
     * @return 返回专家信息
     */
    @Override
    public Response<String> getExportInfo(String cardId, String name, String segmentShowID) throws Exception {
        log.info("======开始验证专家======");
        Response<Map<String, Object>> checkRsp = Response.ok();
        //判断是否业主代表
        Response<Map<String, Object>> rsp = isYzdb(cardId, segmentShowID);
        if(!rsp.isSuccess()) {
            log.info("======非业主代表，开始调用接口验证======");
            //调用接口验证
            checkRsp = checkExpert(cardId, name, segmentShowID);
        } else {
            log.info("======业主代表，跳过接口验证，直接保存信息======");
        }
        if(checkRsp.isSuccess()) {
//            获取接口返回的专家信息
            String ptExpertId = "";
            Date valid = null;
            Map<String, Object> person = checkRsp.getResult();
            if(person != null) {
                ptExpertId = OConvertUtils.getString(person.get("guid"));
                valid = DateUtil.stringToDate(OConvertUtils.getString(person.get("lastAppoinEndtDate"))
                        , "yyyy-MM-dd HH:mm:ss");
            }
            //删除老专家
            Map<String, Object> params = new HashMap<>(4);
            params.put("segmentShowID", segmentShowID);
            params.put("ptExpertId", ptExpertId);
            sectionInfoMapper.deleteOldExpert(params);
            //添加新专家
            Map<String, Object> expert = rsp.getResult();
            int expertType = OConvertUtils.getInt(expert.get("expert_type"), 0);
            String format = "%s,%s,%s,%s";
            String firstSpeciality = OConvertUtils.getString(expert.get("first_speciality"));
            String secondSpeciality = OConvertUtils.getString(expert.get("second_speciality"));
            String thirdSpeciality = OConvertUtils.getString(expert.get("third_speciality"));
            String fourSpeciality = OConvertUtils.getString(expert.get("four_speciality"));
            String expertTypeName;
            if(expertType==0) {
                expertTypeName = "技术";
            } else if(expertType==1) {
                expertTypeName = "商务";
            } else {
                expertTypeName = "组长";
            }
            params = new HashMap<>(32);
            Date now = new Date();
            params.put("GUID", UUID.randomUUID().toString());
            params.put("SegmentShowID", segmentShowID);
            params.put("SegmentEvaluationRecordGuid", segmentShowID);
            params.put("PersonGuid", ptExpertId);
            params.put("SingleTime", now);
            params.put("EvaluationEnd", null);
            params.put("PersonIdea", "");
            params.put("CreateTime", now);
            params.put("Modifytime", null);
            params.put("WorkUnit", OConvertUtils.getString(expert.get("work_unit")));
            params.put("Valid", valid);
            params.put("SpecialistProfessional", expertTypeName);
            params.put("SpecialistType", OConvertUtils.getString(expert.get("expert_source_name")));
            params.put("ExpertAptitude", String.format(format, firstSpeciality, secondSpeciality, thirdSpeciality, fourSpeciality));
            params.put("IDcard", cardId);
            params.put("Name", name);
            params.put("PersonCode", OConvertUtils.getString(expert.get("expert_code")));
            sectionInfoMapper.insertNewExpert(params);
            return Response.ok();
        } else {
            return Response.fail(checkRsp.getError());
        }
    }


    /**
     * 获取招标保证金，保存到数据库
     * @param sectionCode 标段编码
     * @return 返回调用结果
     */
    @Override
    public Response<String> getZbDeposit(String sectionCode) throws Exception {
        ApiEnum api = ApiEnum.GET_DEPOSIT;
        String token = api.getToken();
        Map<String, String> params = new HashMap<>(4);
        params.put("code", sectionCode);
        params.put("token", token);
        //调用接口
        Map<String, Object> resultMap = invokeHttpApi(api, params);
        Response<String> rsp = t9ApiSuccess(resultMap);
        //判断是否成功param
        if(rsp.isSuccess()) {
            //获取保证金
            double deposit = OConvertUtils.getDouble(resultMap.get("deposit"), 0);
            //保存数据库
            Map<String, Object> param = new HashMap<>(4);
            param.put("depositMoney", deposit);
            param.put("sectionCode", sectionCode);
            sectionInfoMapper.updateDeposit(param);
            return Response.ok();
        }
        return rsp;
    }
    /**
     * 获取投标单位保证金信息，保存到数据库
     * @param sectionCode 标段编码
     * @return 返回调用结果
     */
    @Override
    public Response<String> getTbDeposit(String sectionCode) throws Exception {
        //调用接口
        ApiEnum api = ApiEnum.ACCEPT_SERVICE_BANK_RETURN;
        log.info("======调用方欣webservice开始======");
        log.info("======调用URL："+api.getUrl()+"======");
        log.info("======调用方法："+api.getMethod()+"======");
        log.info("======调用参数："+api.getAccount()+","+api.getPassword()+","+sectionCode+"======");
        String result = WebServiceUtils.callWebSV(api.getUrl(), api.getMethod(), api.getAccount(), api.getPassword()
                , sectionCode);
        log.info("======返回值："+result+"======");
        log.info("======调用方欣webservice结束======");
        //判断结果是否为空
        if(StringUtils.isNotBlank(result)) {
            if(isArrayJson(result)) {
                List<Map<String, Object>> list = GsonUtil.jsonToListMapWithGson(result);
                //遍历结果
                if(list != null && !list.isEmpty()) {
                    //获取sectionId
                    SectionInfo sectionInfo = sectionInfoMapper.getSectionInfoByCode(sectionCode);
                    String sectionId = sectionInfo.getSeqId();
                    for(Map<String, Object> map:list) {
                        //企业名称
                        String conName = OConvertUtils.getString(map.get("conName"));
                        //保证金
                        double payDepositMoney = OConvertUtils.getDouble(map.get("payAmt"), 0);
                        //缴纳状态
                        int payDeposit = OConvertUtils.getInt(map.get("Status"), 0);
                        //缴纳时间
                        Date payTime = null;
                        String timeStr = OConvertUtils.getString(map.get("payTime"));
                        if(StringUtils.isNotBlank(timeStr)) {
                            payTime = DateUtil.stringToDate(timeStr, "yyyyMMddHHmmss");
                        }
                        Map<String, Object> param = new HashMap<>(8);
                        param.put("depositMoney", payDepositMoney);
                        param.put("sectionId", sectionId);
                        param.put("payDeposit", payDeposit);
                        param.put("payTime", payTime);
                        param.put("conName", conName);
                        param.put("payDepositType", "杭银在线缴纳");

                        //保存数据库
                        sectionEnterpriseMapper.updateEnterpriseDeposit(param);
                    }
                    return Response.ok();
                }
                return Response.fail("没有获取到投标单位保证金信息");
            } else {
                return Response.fail(result);
            }
        }
        return Response.fail("没有获取到投标单位保证金信息");
    }

    /**
     * 获取企业资质审核相关信息
     * @param sectionCode 标段变啊
     * @return 返回调用结果
     */

    @Async("asyncServiceExecutor")
    @Override
    public Response<String> getEnpriseCheck(String sectionCode) throws Exception {
        //调用接口
        ApiEnum api = ApiEnum.GET_ENTERPRISE_CHECK;
        log.info("======调用方欣webservice开始======");
        log.info("======调用URL："+api.getUrl()+"======");
        log.info("======调用方法："+api.getMethod()+"======");
        log.info("======调用参数："+api.getAccount()+","+api.getPassword()+","+sectionCode+"======");
        String result = WebServiceUtils.callWebSV(api.getUrl(), api.getMethod(), api.getAccount(), api.getPassword()
                , sectionCode);
        log.info("======返回值："+result+"======");
        log.info("======调用方欣webservice结束======");
        if(StringUtils.isNotBlank(result)) {
            Matcher match = enterCheckPatten.matcher(result);
            if (match.find()) {
                String enterCheckStr = match.group(1);
                String enterCheckItemStr = match.group(2);
                List<EnterCheck> enterCheckList = GsonUtil.parseJsonArrayWithGson(enterCheckStr, EnterCheck.class);
                List<EnterCheckItem> enterCheckItemList = GsonUtil.parseJsonArrayWithGson(enterCheckItemStr, EnterCheckItem.class);
                //保存数据库
                for(EnterCheck enterCheck:enterCheckList) {
                    enterCheckMapper.insert(enterCheck);
                }

                for(EnterCheckItem checkItem:enterCheckItemList) {
                    enterCheckItemMapper.insert(checkItem);
                }
            } else {
                return Response.fail(result);
            }
        }
        return Response.fail("没有获取到投标单位企业资质审核相关信息");
    }
    /**
     * 推送標錄
     * @param sectionCode 標段編碼
     * @return 返回調用結果
     */
    @Override
    public Response<String> getProjectBLUpdate(String sectionCode) throws Exception {
        ApiEnum api = ApiEnum.GET_PROJECT_BL_UPDATE;
        String token = api.getToken();
        SectionInfo sectionInfo = sectionInfoMapper.getSectionInfoByCode(sectionCode);
        if(sectionInfo == null) {
            return Response.fail("无法查询标段信息");
        }
        String tdProjectId = sectionInfo.getTdProjectId();
        List<Map<String, Object>> list = sectionEnterpriseMapper.getBidInfo(tdProjectId);
        if(list != null && !list.isEmpty()) {
            BlData bl = new BlData(sectionCode);
            for(Map<String, Object> map:list) {
                String orgCode = OConvertUtils.getString(map.get("orgCode"));
                String enterName = OConvertUtils.getString(map.get("enterName"));
                Double bidPrise = OConvertUtils.getDouble(map.get("bidPrise"), 0);
                String time = OConvertUtils.getString(map.get("time"));
                String quality = OConvertUtils.getString(map.get("quality"));
                Date createTime = (Date) map.get("createTime");

                bl.addRow(orgCode, enterName, bidPrise, time, quality, "", createTime);
            }
            Map<String, Object> resultMap = invokeJyWebServiceBase64(api, token, sectionCode, bl.toString());
            if(resultMap!=null) {
                Response<Map<String, Object>> execResult = jYApiSuccess(resultMap);
                if(execResult.isSuccess()) {
                    return Response.ok();
                } else {
                    return Response.fail(execResult.getError());
                }
            } else {
                return Response.fail("接口返回信息為空");
            }

        }
        return Response.fail("标录数据为空");
    }

    private Response<Map<String, Object>> isYzdb(String cardNo, String segmentShowID) {
        Map<String, Object> param = new HashMap<>(4);
        param.put("sectionCode", segmentShowID);
        param.put("cardNo", cardNo);
        Map<String, Object> expert = sectionInfoMapper.selectExpertBySectionCode(param);
        if(expert != null) {
            int expertType = OConvertUtils.getInt(expert.get("expert_source"), 0);
            if(expertType==2) {
                return Response.ok(expert);
            }
        }
        //非业主代表，success是false，但是result里一定要有专家信息
        Response<Map<String, Object>> rsp = Response.fail("专家");
        rsp.setResult(expert);
        rsp.setSuccess(false);
        return rsp;
    }

    private Response<Map<String, Object>> checkExpert(String cardId, String name, String segmentShowID) throws Exception {
        ApiEnum api = ApiEnum.GET_EXPORT_INFO;
        log.info("======调用方欣webservice开始======");
        log.info("======调用URL："+api.getUrl()+"======");
        log.info("======调用方法："+api.getMethod()+"======");
        log.info("======调用参数："+cardId+","+segmentShowID+","+name+"======");
        Object result = WebServiceUtils.callWebSVObj(api.getUrl(), api.getMethod(), cardId, segmentShowID, name);
        log.info("======返回值："+result+"======");
        log.info("======调用方欣webservice结束======");
        if (result != null) {
            String json = GsonUtil.toJsonWithGson(result);
            log.info("接口返回："+json);
            if (isObjectJson(json)) {
                Map<String, Object> expertInfo = GsonUtil.jsonToMapWithGson(json);
                if (expertInfo.containsKey(KEY_EXPERT_ERROR)) {
                    Map<String, Object> error = (Map<String, Object>) expertInfo.get(KEY_EXPERT_ERROR);
                    if (error != null) {
                        String id = OConvertUtils.getString(error.get("id"));
                        if (CharConstant.CHAR_ZERO.equals(id)) {
                            if (expertInfo.containsKey(KEY_EXPERT_PERSON)) {
                                log.info("验证成功");
                                return Response.ok((Map<String, Object>)expertInfo.get(KEY_EXPERT_PERSON));
                            } else {
                                return Response.fail(EXPERT_RESULT_INCOMPLETE);
                            }
                        } else {
                            log.info("验证失败："+error.get("describe"));
                            return Response.fail(OConvertUtils.getString(error.get("describe")));
                        }
                    } else {
                        return Response.fail(EXPERT_RESULT_INCOMPLETE);
                    }
                } else {
                    return Response.fail(EXPERT_RESULT_INCOMPLETE);
                }
            } else {
                return Response.fail("专家验证接口返回值错误");
            }
        } else {
            log.info("接口返回值为空");
            return Response.fail("专家验证接口返回值为空");
        }
    }

    @Autowired(required = false)
    private ApiSectionInfoMapper sectionInfoMapper;
    @Autowired(required = false)
    private ApiSectionEnterpriseMapper sectionEnterpriseMapper;
    @Autowired(required = false)
    private ApiEnterCheckItemMapper enterCheckItemMapper;
    @Autowired(required = false)
    private ApiEnterCheckMapper enterCheckMapper;
}
